package repository

import (
	"gin-shop-admin/dao"
	"gin-shop-admin/models"
	"strconv"
)

type Cate struct {
	ID     int `gorm:"column:cat_id" json:"cat_id"`
	Name   string `gorm:"column:cat_name" json:"cat_name"`
	Pid    int `gorm:"column:cat_pid" json:"cat_pid"`
	Level int `gorm:"column:cat_level" json:"cat_level"`
	Deleted bool `gorm:"column:cat_deleted" json:"cat_deleted"`
	Children []*Cate `json:"children"`
}

func (Cate)TableName() string {
	return "sp_category"
}


func GetGoodsCategory(request_type string, pageNum string, pageSize string) (total int, cates []*Cate, err error) {
	if err = dao.DB.Model(&models.Category{}).Where("cat_level=?", 0).Count(&total).Error; err != nil {
		return 0, nil, err
	}
	var data_type int
	if request_type == ""{
		data_type = 3
	}else {
		data_type, _ = strconv.Atoi(request_type)
	}
	// 若数据类型为1 则只返回level为1的商品分类
	if data_type == 1{
		if pageNum != "" && pageSize != "" {
			page_num,_ := strconv.Atoi(pageNum)
			page_size,_ := strconv.Atoi(pageSize)
			query_sql := "select cat_id, cat_name, cat_pid, cat_level, cat_deleted from sp_category where cat_level = ? limit ? offset ?"
			dao.DB.Raw(query_sql, 0, page_size, (page_num-1)*page_size).Scan(&cates)
		}else {
			query_sql := "select cat_id, cat_name, cat_pid, cat_level, cat_deleted from sp_category where cat_level = ?"
			dao.DB.Raw(query_sql, 0).Scan(&cates)
		}
		return
	}

	var top_category_list []*Cate
	var top_levle_ids []int

	if pageNum != "" && pageSize != "" {
		page_num,_ := strconv.Atoi(pageNum)
		page_size,_ := strconv.Atoi(pageSize)
		dao.DB.Select("cat_id").Where("cat_level = ?", 0).Limit(page_size).Offset((page_num-1)*page_size).Find(&top_category_list)
	}else {
		dao.DB.Select("cat_id").Where("cat_level = ?", 0).Find(&top_category_list)
	}
	for _, cate := range top_category_list{
		top_levle_ids = append(top_levle_ids, cate.ID)
	}

	var category_list []*Cate
	query_sql := "select cat_id, cat_name, cat_pid, cat_level, cat_deleted from sp_category as a where a.cat_id in (?) or a.cat_pid in (?)"
	dao.DB.Raw(query_sql, top_levle_ids, top_levle_ids).Scan(&category_list)

	if data_type == 3 {
		var level_ids []int
		for _, cate := range category_list{
			level_ids = append(level_ids, cate.ID)
		}
		dao.DB.Raw(query_sql, level_ids, level_ids).Scan(&category_list)
	}
	cates = GetCategoryTree(category_list, top_levle_ids)
	return
}

func GetCategoryTree(category_list []*Cate, top_level_ids []int)(cates []*Cate) {
	var category_map map[int]*Cate
	category_map = make(map[int]*Cate)
	for _, category := range category_list {
		category_map[category.ID] = category
	}
	for _, category := range category_list{
		if category.Pid != 0 {
			category_map[category.Pid].Children = append(category_map[category.Pid].Children, category)
		}
	}
	for _, cat_id := range top_level_ids{
		cates = append(cates, category_map[cat_id])
	}
	return
}

func AddOneCategory(cate models.Category) error {
	return dao.DB.Create(&cate).Error
}

func UpdateOneCategory(cate models.Category) error {
	return dao.DB.Model(&cate).Update(models.Category{Name:cate.Name}).Error
}

func DeleteOneCategory(id int) error {
	var cates []models.Category
	dao.DB.Select("cat_id").Where(&models.Category{Pid: id}).Find(&cates)
	if len(cates) > 0 {
		var deleted_ids []int
		deleted_ids = append(deleted_ids, id)
		for _, cate := range cates {
			deleted_ids = append(deleted_ids, cate.ID)
		}
		return dao.DB.Delete(models.Category{}, "cat_id in (?) or cat_pid in (?)", deleted_ids, deleted_ids).Error
	} else {
		return dao.DB.Delete(&models.Category{ID: id}).Error
	}
}

func GetCategoryAttribute(cat_id int, sel string) (attrs []models.ShopAttribute, err error) {
	if err = dao.DB.Where(&models.ShopAttribute{CatID:cat_id, AttrSel:sel}).Find(&attrs).Error; err!=nil{
		return nil, err
	}
	return
}

func AddCategoryAttribute(attr models.ShopAttribute) error {
	return dao.DB.Save(&attr).Error
}

func GetCategoryOneAttribute(cat_id int, attr_id int, attr_sel string)(attr models.ShopAttribute, err error)  {
	if err = dao.DB.Where(&models.ShopAttribute{CatID:cat_id, ID:attr_id, AttrSel:attr_sel}).First(&attr).Error; err != nil{
		return
	}
	return
}

func UpdateCategoryAttribute(attr models.ShopAttribute, name string, vals string) error {
	if vals == ""{
		return dao.DB.Model(&models.ShopAttribute{}).Where(&attr).UpdateColumn("attr_name", name).Error
	}
	return dao.DB.Model(&models.ShopAttribute{}).Where(&attr).UpdateColumns(models.ShopAttribute{Name:name,AttrVals:vals}).Error
}

func DeleteOneAttribute(cat_id int, attr_id int) error {
	return dao.DB.Delete(&models.ShopAttribute{ID:attr_id, CatID:cat_id}).Error
	//return dao.DB.Model(&models.ShopAttribute{}).Where(&models.ShopAttribute{ID:attr_id, CatID:cat_id}).UpdateColumn("delete_time", time.Now()).Error
}